home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl1 / examples / porting / xsolar_irisgl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  10.7 KB  |  419 lines

  1. /*
  2.  * Copyright 1993, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*                xsolar_irisgl.c
  18.  *    Displays a planet with a moon, orbiting a sun.
  19.  *     Uses X and IRIS GL widget.
  20.  *
  21.  *    Exit with the ESCape key or through the window manager menu.
  22.  */
  23. #include <Xm/Xm.h>
  24. #include <Xm/Frame.h>
  25. #include <Xm/Form.h>
  26. #include <X11/Xirisw/GlxMDraw.h>
  27. #include <X11/StringDefs.h>
  28. #include <X11/keysym.h>
  29.  
  30. #include <gl/gl.h>
  31. #include <gl/device.h>
  32. #include <gl/get.h>
  33. #include <stdio.h>
  34. #include <math.h>
  35.  
  36. typedef struct _spin {
  37.     short year;
  38. } SPINDATA, *SPINPTR;
  39.  
  40. /* function prototypes */
  41.  
  42. void main(int argc, char **argv);
  43.  
  44. void initCB (Widget w, XtPointer client_data, XtPointer call_data);
  45. void exposeCB (Widget w, XtPointer spin, XtPointer call_data);
  46. void resizeCB (Widget w, XtPointer spin, XtPointer call_data);
  47. void inputCB (Widget w, XtPointer client_data, XtPointer call_data);
  48.  
  49. Boolean drawWP (XtPointer spin);
  50.  
  51. void drawscene(SPINPTR spin);
  52. void setbeachball(int stripes);
  53. void beachball(unsigned long color1, unsigned long color2);
  54.  
  55. SPINPTR spin;
  56.  
  57. static XtAppContext app_context;
  58. static XtWorkProcId workprocid = NULL;
  59.  
  60. /* Create application context, and a form widget to contain
  61.  * the IRIS GL widget.  Set up the IRIS GL widget callbacks
  62.  */
  63. void main(int argc, char **argv)
  64. {
  65.     Arg wargs[15];
  66.     int n;
  67.     Widget glw, toplevel, frame, form;
  68.  
  69.     static GLXconfig glxConfig [] = {
  70.         {GLX_NORMAL, GLX_DOUBLE, TRUE},
  71.         {GLX_NORMAL, GLX_RGB, TRUE},
  72.         {GLX_NORMAL, GLX_ZSIZE, GLX_NOCONFIG},
  73.         {0, 0, 0}
  74.     };    
  75.  
  76.     static String fallback_resources[] = {
  77.         "*frame*shadowType: SHADOW_IN",
  78.         "*glwidget*width: 750",
  79.         "*glwidget*height: 600",
  80.         NULL
  81.     };
  82.  
  83.     /*    create main data structure, spin pointer    */
  84.     spin = (SPINPTR) malloc (sizeof (SPINDATA));
  85.     spin->year = 0;
  86.  
  87.     toplevel = XtAppInitialize(
  88.             &app_context,    /* Application context */
  89.             "XSolar",    /* Application class */
  90.             NULL, 0,     /* command line option list */
  91.             &argc, argv,    /* command line args */
  92.             fallback_resources,
  93.             NULL,        /*  argument list  */
  94.             0);        /* number of arguments */
  95.  
  96.     n = 0;
  97.     form = XmCreateForm(toplevel, "form", wargs, n);
  98.     XtManageChild(form);
  99.  
  100.     n = 0;
  101.     XtSetArg(wargs[n], XtNx, 30); n++;
  102.     XtSetArg(wargs[n], XtNy, 30); n++;
  103.     XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  104.     XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  105.     XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  106.     XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
  107.  
  108.     XtSetArg(wargs[n], XmNleftOffset, 30); n++;
  109.     XtSetArg(wargs[n], XmNbottomOffset, 30); n++;
  110.     XtSetArg(wargs[n], XmNrightOffset, 30); n++;
  111.     XtSetArg(wargs[n], XmNtopOffset, 30); n++;
  112.     frame = XmCreateFrame (form, "frame", wargs, n);
  113.     XtManageChild (frame);
  114.  
  115.     n = 0;
  116.     XtSetArg(wargs[n], GlxNglxConfig, glxConfig); n++;
  117.     glw = GlxCreateMDraw(frame, "glwidget", wargs, n);
  118.     XtManageChild (glw);
  119.     XtAddCallback(glw, GlxNginitCallback, initCB, 
  120.         (XtPointer) NULL);
  121.     XtAddCallback(glw, GlxNexposeCallback, exposeCB, 
  122.         (XtPointer) spin);
  123.     XtAddCallback(glw, GlxNresizeCallback, resizeCB, 
  124.         (XtPointer) spin);
  125.     XtAddCallback(glw, GlxNinputCallback, inputCB, 
  126.         (XtPointer) NULL);
  127.  
  128.     workprocid = XtAppAddWorkProc (app_context, drawWP, 
  129.         (XtPointer) spin);
  130.  
  131.     XtRealizeWidget(toplevel);    /* instantiate it now */
  132.     XtAppMainLoop(app_context);    /* loop for events */
  133. }    /*   end main()   */
  134.  
  135. /*        initCB     
  136.  *    The initCB subroutine initializes graphics modes and
  137.  *    transformation matrices.
  138.  */
  139.  
  140. void initCB (Widget w, XtPointer client_data, XtPointer call_data)
  141. {
  142.     long gid1, xmax, ymax;
  143.     float aspect;
  144.  
  145.     GLXwinset(XtDisplay(w), XtWindow(w));
  146.  
  147.     xmax = getgdesc(GD_XPMAX);
  148.     ymax = getgdesc(GD_YPMAX);
  149.     if (getgdesc(GD_BITS_NORM_ZBUFFER) == 0)
  150.     {
  151.         fprintf(stderr, 
  152.             "This machine does not have a hardware zbuffer\n");
  153.         exit(0);
  154.     }
  155.  
  156.     zbuffer(TRUE);
  157.     shademodel(FLAT);
  158.  
  159.     qdevice(LEFTMOUSE);
  160.     qdevice(MIDDLEMOUSE);
  161.     qdevice(ESCKEY);
  162.     tie(LEFTMOUSE, MOUSEX, MOUSEY);
  163.  
  164.     /* separtae ModelView and Projection matrix stacks;
  165.      * both are initialized with an identity matrix.
  166.      */
  167.     mmode(MVIEWING);
  168.     aspect = (float) xmax / (float) ymax;
  169.  
  170.     /* projection commands replace projection matrix */
  171.     perspective(450, aspect, 1.0, 25.0);
  172.  
  173.     /* viewing commands premultiply the ModelView matrix */
  174.     polarview(12.0, 0, -100, 0);
  175. }    /*   end initCB()   */
  176.  
  177. /*    exposeCB() and resizeCB() are called when the window
  178.  *    is uncovered, moved, or resized.
  179.  */
  180.  
  181. void exposeCB (Widget w, XtPointer ptr, XtPointer call_data)
  182. {
  183.     SPINPTR spin;
  184.  
  185.     spin = (SPINPTR) ptr;
  186.     GLXwinset (XtDisplay(w), XtWindow(w));
  187.     drawscene(spin);
  188. }
  189.  
  190. void resizeCB (Widget w, XtPointer ptr, XtPointer call_data)
  191. {
  192.     GlxDrawCallbackStruct *call_ptr;
  193.     SPINPTR spin;
  194.  
  195.     spin = (SPINPTR) ptr;
  196.     call_ptr = (GlxDrawCallbackStruct *) call_data;
  197.     GLXwinset (XtDisplay(w), XtWindow(w));
  198.     viewport (0, (Screencoord) call_ptr->width-1,
  199.         0, (Screencoord) call_ptr->height-1);
  200.     drawscene(spin);
  201. }
  202.  
  203. /*    inputCB() handles all types of input from the GL widget.
  204.  *    The KeyRelease handles the ESCape key, so that it exits
  205.  *    the program.  
  206.  */
  207. void inputCB (Widget w, XtPointer client_data, 
  208.     XtPointer call_data)
  209. {
  210.     char buffer[1];
  211.     KeySym keysym;
  212.     GlxDrawCallbackStruct *call_ptr = 
  213.                 (GlxDrawCallbackStruct *) call_data;
  214.     XKeyEvent *kevent = (XKeyEvent *) (call_ptr->event);
  215.  
  216.     switch(call_ptr->event->type) {
  217.     case KeyRelease:
  218.         /* It is necessary to convert the keycode to a 
  219.          * keysym before checking if it is an escape */
  220.         if (XLookupString(kevent,buffer,1,&keysym,NULL) == 1 
  221.             && keysym == (KeySym)XK_Escape)
  222.             exit(0);
  223.         break;
  224.     default:
  225.         break;
  226.     }
  227. }
  228.  
  229. /*    drawWP() is called by the WorkProc.  When the scene
  230.  *    is in automatic motion, the WorkProc calls this routine,
  231.  *    which adds 1 degree (10 tenths) to the cumulative amount
  232.  *    of rotation.  drawscene() is called, so the image is
  233.  *    redrawn.  It returns(FALSE) so the WorkProc does not
  234.  *    discontinue operation.
  235.  */
  236. Boolean drawWP (XtPointer ptr)
  237. {
  238.     SPINPTR spin;
  239.  
  240.     spin = (SPINPTR) ptr;
  241.     spin->year = (spin->year + 10) % 3600;
  242.     drawscene (spin);
  243.     return (FALSE);
  244. }
  245.  
  246.  
  247. /*    drawscene calculates angles relative to the spin->year
  248.  *    and then draws sun, planet, and moon.
  249.  */
  250.  
  251. void drawscene(SPINPTR spin)
  252. {
  253.     static long blackcol[] = { 0, 0, 0 };
  254.     static long bluecol[] = { 0, 0, 255 };
  255.     static long whitecol[] = { 255, 255, 255 };
  256.     short sunangle, dayangle, monthangle;
  257.     /* actual 1.5e8 kM * 3.0e-9 fudgefactor */
  258.     float earthdist = 4.5, earthscale = 0.5;
  259.     float moondist = 0.9, moonscale = 0.2;
  260.  
  261.     c3i(blackcol);
  262.     /* clear color & z buffers */
  263.     czclear(getgdesc(GD_ZMIN),getgdesc(GD_ZMAX)); 
  264.     pushmatrix();
  265.     sunangle = (spin->year*365/25) % 3600;
  266.     /* sun rotates on axis every 25 days */
  267.     rotate(sunangle, 'y');
  268.     beachball(0x20C0FF, 0x200FFFF); /* colors in cpack format */
  269.     popmatrix();
  270.     pushmatrix();
  271.     rotate(spin->year, 'y');
  272.     translate(earthdist, 0.0, 0.0);
  273.     pushmatrix();
  274.     dayangle = (spin->year*50) % 3600; /* fudged */
  275.     rotate(dayangle, 'y');
  276.     scale(earthscale, earthscale, earthscale);
  277.     c3i(bluecol);
  278.     beachball(0xFF0000, 0xC02000); /* earth */
  279.     popmatrix();
  280.     monthangle = (spin->year*365/28) % 3600;
  281.     rotate(monthangle, 'y');
  282.     translate (moondist, 0.0, 0.0);
  283.     scale(moonscale, moonscale, moonscale);
  284.     c3i(whitecol);
  285.     beachball(0xFFFFFF, 0xC0C0C0); /* moon */
  286.     popmatrix();
  287.  
  288.     swapbuffers();
  289. }   /*  end drawscene()  */
  290.  
  291. /* BEACHBALL */
  292.  
  293. /* three dimensional vector */
  294. typedef float vector[3];
  295.  
  296. static vector front  = { 0.0,  0.0,  1.0 };
  297. static vector back   = { 0.0,  0.0, -1.0 };
  298. static vector top    = { 0.0,  1.0,  0.0 };
  299. static vector bottom = { 0.0, -1.0,  0.0 };
  300. static vector right  = { 1.0,  0.0,  0.0 };
  301. static vector left   = { -1.0,  0.0,  0.0 };
  302. static vector center = { 0.0,  0.0,  0.0 };
  303.  
  304. /* Number of colored stripes. Should be even to look right */
  305. #define BEACHBALL_STRIPES 12
  306.  
  307. /* Default number of polygons  making up a stripe. Should be even */
  308. #define BEACHBALL_POLYS 16
  309.  
  310. /* array of vertices making up a stripe */
  311. static vector stripe_point[BEACHBALL_POLYS + 3];
  312.  
  313. /* has the beachball been initialized */
  314. static Boolean beachball_initialized = FALSE;
  315.  
  316. /* Number of polygons making up a stripe */
  317. static int beachball_stripes;
  318.  
  319. /* Number of vertices making up a stripe */
  320. static int stripe_vertices;
  321.  
  322. /* Initialize beachball_point array to be a stripe 
  323.  * of unit radius.
  324.  */
  325. void setbeachball(int stripes)
  326. {
  327.     int i,j;
  328.     float x,y,z;             /* vertex points */
  329.     float theta,delta_theta;    /* angle from top pole to bottom pole */
  330.     float offset;         /* offset from center of stripe to vertex */
  331.     float cross_radius; /* radius of cross section at current latitude */
  332.     float cross_theta;  /* angle occupied by a stripe  */
  333.  
  334.     beachball_stripes = stripes;
  335.  
  336.     /* polys distributed by even angles from top to bottom */
  337.     delta_theta = M_PI/((float)BEACHBALL_POLYS/2.0);
  338.     theta = delta_theta;
  339.  
  340.     cross_theta = 2.0*M_PI/(float)beachball_stripes;
  341.  
  342.     j = 0;
  343.  
  344.     stripe_point[j][0] = top[0];
  345.     stripe_point[j][1] = top[1];
  346.     stripe_point[j][2] = top[2];
  347.     j++;
  348.  
  349.     for (i = 0; i < BEACHBALL_POLYS; i += 2) {
  350.         cross_radius = fsin(theta);
  351.         offset = cross_radius * ftan(cross_theta/2.0);
  352.  
  353.         stripe_point[j][0] = - offset;
  354.         stripe_point[j][1] = fcos(theta);
  355.         stripe_point[j][2] = cross_radius;
  356.         j++;
  357.  
  358.         stripe_point[j][0] = offset;
  359.         stripe_point[j][1] = stripe_point[j-1][1];
  360.         stripe_point[j][2] = stripe_point[j-1][2];
  361.         j++;
  362.  
  363.         theta += delta_theta;
  364.     }
  365.  
  366.     stripe_point[j][0] = bottom[0];
  367.     stripe_point[j][1] = bottom[1];
  368.     stripe_point[j][2] = bottom[2];
  369.  
  370.     stripe_vertices = j + 1;
  371.  
  372.     beachball_initialized = TRUE;
  373. }
  374.  
  375. /*
  376.  *    Draws a canonical beachball.  The colors are cpack values 
  377.  *    when in RGBmode, colormap indices when in colormap mode.
  378.  */
  379. void beachball(unsigned long c1, unsigned long c2)
  380. {
  381.     long mode;
  382.     float angle, delta_angle;
  383.     int i,j;
  384.  
  385.     if (! beachball_initialized)
  386.         setbeachball(BEACHBALL_STRIPES);
  387.  
  388.     mode = getdisplaymode();
  389.  
  390.     angle = 0.0;
  391.     delta_angle = 360.0/(float)beachball_stripes;
  392.  
  393.     for (i = 0; i < beachball_stripes; i++) {
  394.         switch(mode) {
  395.         case DMSINGLE: case DMDOUBLE:
  396.             if ( i%2 == 0)
  397.                 color(c1);
  398.             else color(c2);
  399.             break;
  400.         case DMRGB: case DMRGBDOUBLE:
  401.             if ( i%2 == 0)
  402.                 cpack(c1);
  403.             else cpack(c2);
  404.             break;
  405.         }
  406.  
  407.         pushmatrix();
  408.         rot(angle, 'y');
  409.         angle += delta_angle;
  410.  
  411.         bgntmesh();
  412.             for (j = 0; j < stripe_vertices; j++)
  413.                 v3f(stripe_point[j]);
  414.         endtmesh();
  415.         popmatrix();
  416.     }
  417. }
  418.  
  419.